package com.zyn.inventory.management.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.zyn.inventory.management.enums.LoginError;
import com.zyn.inventory.management.forms.RegistrationForm;
import com.zyn.inventory.management.forms.Result;
import com.zyn.inventory.management.validator.RegistrationValidator;

@Controller
@RequestMapping("/auth")
public class LogoutController {
	private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Resource
    private RegistrationValidator registrationValidator;

    private static final String SPRING_SECURITY_LAST_EXCEPTION = "SPRING_SECURITY_LAST_EXCEPTION";

    @InitBinder("registrationForm")
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(registrationValidator);
    }
    
    
    /**
     * Handles and retrieves the login JSP page
     *
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String showLoginPage(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "error", required = false) boolean error, ModelMap model) {

        log.info("Received request to show login page");

//        invalidateSession(request, response);

//        request.getSession(false).removeAttribute("continueAttribute");


        if (error) {
            model.put("error", generateLoginErrorMessage(request.getSession(false)));
        }
        return "login";
    }

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String showRegistrationPage(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam(required = false) String email) {

//        invalidateSession(request, response);

        if (!model.containsAttribute("registrationForm")) {
            RegistrationForm registrationForm = new RegistrationForm();
            model.addAttribute("registrationForm", registrationForm);
        }

        model.addAttribute("activeTab", "register");

        return "loginTH";
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String register(Model model, HttpServletRequest request, HttpServletResponse response, @ModelAttribute("registrationForm") @Validated RegistrationForm registrationForm, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return showRegistrationPage(request, response, model, null);
        }

//        invalidateSession(request, response);

        

        String[] codes = {"registration.failure"};

        ObjectError error = new ObjectError("registrationForm", codes, null, null);
        bindingResult.addError(error);

        return showRegistrationPage(request, response, model, null);
    }

    @RequestMapping(value = "/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
//        invalidateSession(request, response);

        return "redirect:/auth/login";
    }

    /**
     * Handles and retrieves the denied JSP page. This is shown whenever a regular user
     * tries to access an admin only page.
     *
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/denied", method = RequestMethod.GET)
    public String getDeniedPage() {
        log.info("received request to show denied page");

        // This will resolve to /WEB-INF/jsp/deniedpage.jsp
        return "deniedpage";
    }

    @RequestMapping(value = "/forgotPassword", method = RequestMethod.GET)
    public String viewForgotPasswordPage(HttpServletRequest request, Model model) {
        model.addAttribute("activeTab", "forgotPassword");
        model.addAttribute("registrationForm", new RegistrationForm());

        return "login";
    }

    @RequestMapping(value = "/forgotPassword", method = RequestMethod.POST)
    public
    @ResponseBody
    Result forgotPassword(HttpServletRequest request, HttpServletResponse response, @RequestParam String email) {
//        invalidateSession(request, response);

        Result result = new Result();
        result.setResult(false);
        return result;
    }

    private LoginError generateLoginErrorMessage(HttpSession session) {
        if (session != null) {
            Exception exception = (Exception) session.getAttribute(SPRING_SECURITY_LAST_EXCEPTION);
            if (exception != null) {
                if (exception instanceof BadCredentialsException) {
                    return LoginError.INVALID_CREDENTIALS;
                } else {
                    return LoginError.OTHER;
                }
            }
        }

        return null;
    }
}
